home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume12 / acm / part08 < prev    next >
Encoding:
Internet Message Format  |  1991-03-01  |  18.7 KB

  1. Path: uunet!spool.mu.edu!sdd.hp.com!wuarchive!decwrl!sun-barr!newstop!male!jethro!exodus!mipsdal.mips.com
  2. From: riley@mipsdal.mips.com (Riley Rainey)
  3. Newsgroups: comp.sources.x
  4. Subject: v12i013: acm - X aerial combat simulation, Part08/09
  5. Message-ID: <8990@exodus.Eng.Sun.COM>
  6. Date: 2 Mar 91 08:32:52 GMT
  7. References: <csx-12i006:acm@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 761
  10. Approved: argv@sun.com
  11. Posted: Sat Mar  2 02:32:52 1991
  12.  
  13. Submitted-by: riley@mipsdal.mips.com (Riley Rainey)
  14. Posting-number: Volume 12, Issue 13
  15. Archive-name: acm/part08
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 8 (of 9)."
  24. # Contents:  acm/fsim/pm.c
  25. # Wrapped by riley@mipsdal on Thu Feb 14 10:09:21 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'acm/fsim/pm.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'acm/fsim/pm.c'\"
  29. else
  30. echo shar: Extracting \"'acm/fsim/pm.c'\" \(16393 characters\)
  31. sed "s/^X//" >'acm/fsim/pm.c' <<'END_OF_FILE'
  32. X/*
  33. X *    xflight : an aerial combat simulator for X
  34. X *
  35. X *    Written by Riley Rainey,  riley@mips.com
  36. X *
  37. X *    Permission to use, copy, modify and distribute (without charge) this
  38. X *    software, documentation, images, etc. is granted, provided that this 
  39. X *    comment and the author's name is retained.
  40. X *
  41. X */
  42. X#include <stdio.h>
  43. X#include <math.h>
  44. X#include "pm.h"
  45. X
  46. Xint debug = 0;
  47. X
  48. X/*
  49. X *  A Flight Simulator
  50. X *
  51. X *  Riley Rainey
  52. X */
  53. X
  54. X/*
  55. X *  We keep a table of atmospheric constants for different altitudes.
  56. X *  These values are important to flight calculations.
  57. X */
  58. X
  59. Xstruct {
  60. X    double    alt;        /* altitude in feet */
  61. X    double    rho;        /* rho value (air density) */
  62. X    double    mach1;        /* speed of sound in feet per second */
  63. X    } *rhop, rhoTable[] = {
  64. X    0.0, 23.77, 1116.9,
  65. X    2.0, 22.41, 1109.2,
  66. X    4.0, 21.11, 1101.4,
  67. X    6.0, 19.87, 1093.6,
  68. X    8.0, 18.68, 1085.7,
  69. X    10.0, 17.55, 1077.8,
  70. X    15.0, 14.96, 1057.7,
  71. X    20.0, 12.66, 1037.3,
  72. X    25.0, 10.65, 1016.4,
  73. X    30.0,  8.89,  995.1,
  74. X    35.0,  7.365, 973.3,
  75. X    40.0,  5.851, 968.5,
  76. X    50.0,  3.618, 968.5,
  77. X    60.0,  2.238, 968.5,
  78. X    80.0,  0.9065, 980.0,
  79. X    100.0, 0.3371, 1015.0,
  80. X    120.0, 0.1340, 1053.0,
  81. X    160.0, 0.02622, 1083.0,
  82. X    100000.0, 0.02622, 1083.0};    /* a large value for alt at the end */
  83. X
  84. Xdouble        deltaT;        /* Update interval in seconds */
  85. Xdouble        halfDeltaTSquared; /* 0.5 * deltaT * deltaT */
  86. Xdouble        CM, CN, CY;
  87. X
  88. X/*
  89. X *  calcRho : Calculate air density and the speed of sound by interpolation.
  90. X */
  91. X
  92. Xdouble calcRho (alt, mach)
  93. Xdouble alt;
  94. Xdouble *mach; {
  95. X
  96. X    double    deltaAlt, b;
  97. X
  98. X    alt = alt / 1000.0;
  99. X
  100. X    for (rhop=rhoTable; alt>(rhop+1)->alt; ++rhop) ;
  101. X    deltaAlt = (rhop+1)->alt - rhop->alt;
  102. X    b = ((rhop+1)->mach1 - rhop->mach1) / deltaAlt;
  103. X    *mach = rhop->mach1 + b * (alt - rhop->alt);
  104. X    b = ((rhop+1)->rho - rhop->rho) / deltaAlt;
  105. X    return (rhop->rho + b * (alt - rhop->alt)) / 10000.0;
  106. X
  107. X}
  108. X
  109. X/*
  110. X *  twoorder:
  111. X */
  112. X
  113. Xvoid twoOrder (k, d, y, v, newy, newv)
  114. Xdouble    k, d, y, v;
  115. Xdouble    *newy, *newv; {
  116. X
  117. X    double    s, t, ac, x, c1;
  118. X
  119. X    ac = d * d + 4.0 * k;
  120. X    if (ac < 0.0) {
  121. X        s = d / 2.0;
  122. X        t = sqrt (-ac) / 2.0;
  123. X    }
  124. X    else {
  125. X        s = - d - sqrt(ac) / 2.0;
  126. X        t = 0.0;
  127. X    }
  128. X
  129. X    if (t == 0.0 || y == 0.0)
  130. X        x = 0.0;
  131. X    else
  132. X        x = atan2 ( y * s - v, t * y ) / t;
  133. X
  134. X    if (x == 0.0)
  135. X        c1 = y;
  136. X    else if (cos (t * x) != 0.0)
  137. X        c1 = y / ( exp (s * x) * cos (t * x) );
  138. X    else {
  139. X        *newy = 0.0;
  140. X        *newv = v;
  141. X    }
  142. X
  143. X/*
  144. X *  Now we can compute the values of y and v at the end of this
  145. X *  time interval;
  146. X */
  147. X
  148. X#ifdef notdef
  149. X    printf ("s = %g, t = %g, x = %g, y = %g, c1 = %g\n", s, t, x,
  150. X        y, c1);
  151. X
  152. X    if (fabs (y - (exp(s*x) * c1 * cos(t * x))) > 0.001)
  153. X        printf ("*** possible error ***\n");
  154. X
  155. X    *newv = exp(s*x) * c1 * (s * cos(t*x) - t*sin(t*x));
  156. X    if (fabs (v - *newv) > 0.001)
  157. X        printf ("*** possible v error *** %g %g\n", v, *newv);
  158. X#endif
  159. X
  160. X    x += deltaT;
  161. X
  162. X    *newy = exp (s * x) * c1 * cos (t * x);
  163. X    *newv = exp (s * x) * c1 * (s * cos (t * x) - t * sin (t * x));
  164. X
  165. X#ifdef notdef
  166. X    printf ("ny = %g, nv = %g\n", *newy, *newv);
  167. X#endif
  168. X
  169. X}
  170. X
  171. X
  172. X/*
  173. X *  calcCoefficients :  Calculate CLift and friends
  174. X */
  175. X
  176. Xvoid calcCoefficients (c, CLift, CDrag)
  177. Xcraft     *c;
  178. Xdouble  *CLift, *CDrag; {
  179. X
  180. X    double CDAlpha, CDBeta;
  181. X
  182. X/*
  183. X *  We used to interpolate these values, but now use several characteristic
  184. X *  equations to compute these values for a given alpha value. The basic
  185. X *  formulas are:
  186. X *
  187. X *
  188. X *   C  = C        + (alpha * (C       + sin(curFlap) * cFlap ))
  189. X *    L    LOrigin            LSlope
  190. X *
  191. X *
  192. X *   C  = C        + (C       * Cos (alpha + C      ))
  193. X *    D    DOrigin     DFactor                DPhase
  194. X *
  195. X *  There are independent equations defining drag resulting from alpha
  196. X *  and beta values.  The hypoteneuse of those two values becomes the
  197. X *  resultant CDrag value.
  198. X */
  199. X
  200. X    if (c->alpha < c->cinfo->CLNegStall || c->alpha > c->cinfo->CLPosStall) {
  201. X
  202. X        *CLift = 0.0;
  203. X        CM = c->cinfo->cmFactor + c->damageCM;
  204. X    }
  205. X    else {
  206. X        *CLift = c->cinfo->CLOrigin + 
  207. X            (c->cinfo->CLSlope + sin (c->curFlap) * c->cinfo->cFlap)
  208. X            * c->alpha;
  209. X        CM = c->cinfo->cmSlope + c->damageCM;
  210. X    }
  211. X
  212. X/*    CDAlpha = c->cinfo->CDOrigin + c->cinfo->CDFactor * 
  213. X        cos (c->alpha + c->cinfo->CDPhase);
  214. X*/
  215. X
  216. X    CDAlpha = (*c->cinfo->CDi)(c) +
  217. X/*    CDAlpha = c->cinfo->CDOrigin + */
  218. X        *CLift * *CLift / (pi * c->cinfo->aspectRatio);
  219. X    CDAlpha += sin (c->curSpeedBrake) * c->cinfo->cSpeedBrake;
  220. X    CDAlpha += sin (c->curFlap) * c->cinfo->cFlapDrag;
  221. X
  222. X    if (fabs(c->beta) > c->cinfo->betaStall)
  223. X        CN = c->cinfo->cnFactor * sin (c->beta);
  224. X    else
  225. X        CN = c->cinfo->cnSlope;
  226. X
  227. X    CDBeta = c->cinfo->CDBOrigin + c->cinfo->CDBFactor * 
  228. X        cos (c->beta + c->cinfo->CDBPhase);
  229. X
  230. X    *CDrag = sqrt (CDAlpha * CDAlpha + CDBeta * CDBeta);
  231. X
  232. X    CY = c->cinfo->CYbeta * c->beta * fabs (cos (c->beta));
  233. X
  234. X}
  235. X
  236. Xdouble heading (x)
  237. XVPoint    *x; {
  238. X
  239. X    double    m;
  240. X
  241. X    if (x->x == 0.0 && x->y == 0.0)
  242. X        return 0.0;
  243. X
  244. X    if ((m = atan2 (x->y, x->x)) < 0.0)
  245. X        return (pi * 2.0 + m);
  246. X    else
  247. X        return m;
  248. X}
  249. X
  250. Xvoid euler (c)
  251. Xcraft    *c; {
  252. X
  253. X    register double    i, j, k, m;
  254. X
  255. X/*
  256. X *  Compute the heading ...
  257. X */
  258. X
  259. X    i = c->trihedral.m[0][0];
  260. X    j = c->trihedral.m[1][0];
  261. X    k = c->trihedral.m[2][0];
  262. X
  263. X    if (i == 0.0 && j == 0.0)
  264. X        c->curHeading = 0.0;
  265. X    else if ((m = atan2 (j, i)) < 0.0)
  266. X        c->curHeading = pi * 2.0 + m;
  267. X    else
  268. X        c->curHeading = m;
  269. X
  270. X
  271. X/*
  272. X *  and Pitch ...
  273. X */
  274. X
  275. X    c->curPitch = - asin (k);
  276. X
  277. X/*
  278. X *  and Roll ...
  279. X */
  280. X
  281. X    c->curRoll = atan2 (c->trihedral.m[2][1], c->trihedral.m[2][2]);
  282. X
  283. X}
  284. X
  285. Xvoid craftToGround (c, p, g)
  286. Xcraft  *c;
  287. XVPoint *p;
  288. XVPoint *g; {
  289. X
  290. X    VTransform (p, &(c->trihedral), g);
  291. X
  292. X}
  293. X
  294. Xvoid calcGForces (c, f, w)
  295. Xcraft *c;
  296. XVPoint *f;
  297. Xdouble w; {
  298. X
  299. X    VPoint t;
  300. X
  301. X    t = *f;
  302. X    t.z -= w;
  303. X
  304. X    VTransform (&t, &(c->Itrihedral), &(c->G));
  305. X    c->G.x = - c->G.x / w;
  306. X    c->G.y = - c->G.y / w;
  307. X    c->G.z = - c->G.z / w;
  308. X}
  309. X
  310. Xvoid calcAlphaBeta (c, alpha, beta)
  311. Xcraft *c;
  312. Xdouble *alpha, *beta; {
  313. X
  314. X    VPoint    C;
  315. X    double    h;
  316. X
  317. X    if (mag(c->Cg) > 0.0) {
  318. X        VTransform (&(c->Cg), &(c->Itrihedral), &C);
  319. X        *alpha = atan2 (C.z, C.x);
  320. X        h = sqrt (C.z * C.z + C.x * C.x);
  321. X        *beta = atan2 (C.y, h);
  322. X    }
  323. X    else {
  324. X        *alpha = 0.0;
  325. X        *beta = 0.0;
  326. X    }
  327. X
  328. X}
  329. X
  330. X/*
  331. X *  buildEulerMatrix :  Build a transformation matrix based on the supplied
  332. X *            euler angles.
  333. X */
  334. X
  335. Xvoid buildEulerMatrix (roll, pitch, heading, m)
  336. Xdouble    roll, pitch, heading;
  337. XVMatrix    *m; {
  338. X
  339. X    register double sinPhi, cosPhi, sinTheta, cosTheta, sinPsi, cosPsi;
  340. X
  341. X    sinPhi = sin (roll);
  342. X    cosPhi = cos (roll);
  343. X    sinTheta = sin (pitch);
  344. X    cosTheta = cos (pitch);
  345. X    sinPsi = sin (heading);
  346. X    cosPsi = cos (heading);
  347. X
  348. X    m->m[0][0] = cosTheta * cosPsi;
  349. X    m->m[0][1] = sinPhi * sinTheta * cosPsi - cosPhi * sinPsi;
  350. X    m->m[0][2] = cosPhi * sinTheta * cosPsi + sinPhi * sinPsi;
  351. X    m->m[1][0] = cosTheta * sinPsi;
  352. X    m->m[1][1] = sinPhi * sinTheta * sinPsi + cosPhi * cosPsi;
  353. X    m->m[1][2] = cosPhi * sinTheta * sinPsi - sinPhi * cosPsi;
  354. X    m->m[2][0] = - sinTheta;
  355. X    m->m[2][1] = sinPhi * cosTheta;
  356. X    m->m[2][2] = cosPhi * cosTheta;
  357. X    m->m[0][3] = m->m[1][3] = m->m[2][3] = 0.0;
  358. X    m->m[3][0] = m->m[3][1] = m->m[3][2] = 0.0;
  359. X    m->m[3][3] = 1.0;
  360. X
  361. X#ifdef notdef
  362. X    VIdentMatrix (m);
  363. X    if (roll != 0.0)
  364. X        VRotate (m, XRotation, roll);
  365. X    if (pitch != 0.0)
  366. X                VRotate (m, YRotation, -pitch);
  367. X    if (heading != 0.0)
  368. X                VRotate (m, ZRotation, heading);
  369. X#endif
  370. X
  371. X}
  372. X
  373. Xint  flightCalculations (c)
  374. Xcraft *c; {
  375. X
  376. X    double    q, CLift, CDrag;
  377. X    double    FLift, FDrag, FWeight, FSideForce;
  378. X    double    Vmag, D, angle;
  379. X    double    ar, ap, aq, cosR, sinR;
  380. X    double  deltaRoll, deltaPitch, deltaYaw;
  381. X    double    muStatic, muKinetic;
  382. X    double    ke, be;
  383. X    double    y, newy;
  384. X    VPoint    F, Fg, V, tmpPt, r;
  385. X    VMatrix turn, mtx, mtx1;
  386. X    int    positionUpdated = 0;
  387. X
  388. X    c->prevSg = c->Sg;
  389. X
  390. X    c->rho = calcRho (-(c->Sg.z), &c->mach1);
  391. X    calcAlphaBeta(c, &(c->alpha), &(c->beta));
  392. X
  393. X/*
  394. X *  A note about thrust:  Normal thrust diminishes in proportion to the decrease in
  395. X *  air density.  Afterburners are not affectected in this way.  The following formula
  396. X *  approximates this effect.
  397. X */
  398. X
  399. X    if (c->fuel <= 0.0 || isFunctioning (c, SYS_ENGINE1) == 0)
  400. X        c->curThrust = 0.0;
  401. X    else
  402. X        c->curThrust = calcThrust(c);
  403. X
  404. X    Vmag = mag(c->Cg);
  405. X    c->mach = Vmag / c->mach1;
  406. X    calcCoefficients (c, &CLift, &CDrag);
  407. X
  408. X    if (debug)
  409. X    printf ("alpha = %g, beta = %g\nCL = %g, CD = %g\n", RADtoDEG(c->alpha),
  410. X        RADtoDEG(c->beta), CLift, CDrag);
  411. X
  412. X
  413. X/*
  414. X *  Compute the resultant force vector on the aircraft.
  415. X */
  416. X
  417. X    q = c->rho * c->cinfo->wingS * Vmag * Vmag * 0.5;
  418. X    FLift = CLift * q;
  419. X    FDrag = CDrag * q;
  420. X    FSideForce = CY * q;
  421. X
  422. X    if (debug) {
  423. X    printf ("rho = %g, FLift = %g, FDrag = %g\n", c->rho, FLift, FDrag);
  424. X    printf ("FThrust = %g\n", c->curThrust);
  425. X    }
  426. X
  427. X    F.x = c->curThrust - sin(c->alpha) * cos(c->beta) * FLift -
  428. X        cos(c->alpha) * cos(c->beta) * FDrag;
  429. X    F.y = sin(c->alpha) * sin(c->beta) * FLift - sin(c->alpha) * sin(c->beta) *
  430. X        FDrag + FSideForce;
  431. X    F.z = -cos(c->alpha) * cos(c->beta) * FLift - sin(c->alpha) * cos(c->beta) *
  432. X        FDrag;
  433. X
  434. X/*
  435. X *  Get ground friction coefficients
  436. X */
  437. X
  438. X    if (c->groundContact)
  439. X    if (c->flags & FL_BRAKES) {
  440. X        muStatic = c->cinfo->muBStatic;
  441. X        muKinetic = c->cinfo->muBKinetic;
  442. X    }
  443. X    else {
  444. X        muStatic = c->cinfo->muStatic;
  445. X        muKinetic = c->cinfo->muKinetic;
  446. X    }
  447. X
  448. X/*
  449. X *  Now calculate changes in position (Sg) and velocity (Cg).
  450. X */
  451. X
  452. X    if (Vmag > c->cinfo->maxNWS || c->groundContact == 0)
  453. X        c->flags &= ~FL_NWS;
  454. X    else
  455. X        c->flags |= FL_NWS;
  456. X
  457. X    if (c->flags & FL_NWS) {
  458. X
  459. X        c->curNWDef = c->Sa * c->cinfo->maxNWDef;
  460. X
  461. X        if (c->curNWDef != 0.0) {
  462. X
  463. X        r.x = c->cinfo->gearD2;
  464. X        r.y = c->cinfo->gearD1 / tan(c->curNWDef);
  465. X        r.z = 0.0;
  466. X        angle = Vmag / r.y * deltaT;
  467. X
  468. X/*
  469. X *  Nose wheel steering mode.
  470. X *  Relocate the aircraft and its trihedral (this code assumes that the
  471. X *  plane is rolling on a flat surface (i.e. z is constant).
  472. X */
  473. X
  474. X        tmpPt = r;
  475. X        VTransform(&tmpPt, &(c->trihedral), &r);
  476. X
  477. X        VIdentMatrix (&turn);
  478. X        turn.m[0][3] = - c->Sg.x - r.x;
  479. X        turn.m[1][3] = - c->Sg.y - r.y;
  480. X        turn.m[2][3] = - c->Sg.z;
  481. X        VRotate (&turn, ZRotation, angle);
  482. X        turn.m[0][3] = turn.m[0][3] + c->Sg.x + r.x;
  483. X        turn.m[1][3] = turn.m[1][3] + c->Sg.y + r.y;
  484. X        turn.m[2][3] = turn.m[2][3] + c->Sg.z;
  485. X        VTransform (&(c->Sg), &turn, &tmpPt);
  486. X        c->Sg = tmpPt;
  487. X
  488. X        VIdentMatrix (&turn);
  489. X        VRotate (&turn, ZRotation, angle);
  490. X        mtx = c->trihedral;
  491. X        VMatrixMult (&mtx, &turn, &(c->trihedral));
  492. X        VTransform (&(c->Cg), &turn, &tmpPt);
  493. X        c->Cg = tmpPt;
  494. X
  495. X            transpose (&c->trihedral, &c->Itrihedral);
  496. X
  497. X        euler (c);
  498. X        positionUpdated = 1;
  499. X        }
  500. X
  501. X        craftToGround (c, &F, &Fg);
  502. X        FWeight = c->cinfo->emptyWeight + c->fuel;
  503. X
  504. X        if ((c->fuel -= fuelUsed(c) + c->leakRate * deltaT) <= 0.0) {
  505. X        c->fuel = 0.0;
  506. X        c->curThrust = 0.0;
  507. X        c->throttle = 0;
  508. X        }
  509. X
  510. X        Fg.z += FWeight;
  511. X
  512. X/*
  513. X *  Factor in ground friction for both static and moving planes.
  514. X */
  515. X
  516. X        if (c->Cg.x + c->Cg.y == 0.0 && sqrt (Fg.x*Fg.x + Fg.y*Fg.y) <=
  517. X        muStatic * Fg.z) {
  518. X            Fg.x = 0.0;
  519. X            Fg.y = 0.0;
  520. X        }
  521. X        else {
  522. X
  523. X/*
  524. X *  Okay, the plane is moving.  Quantify the current kinetic energy of the
  525. X *  moving craft and add the energy added this period by all forces EXCEPT
  526. X *  ground friction (we'll name this "ke").  If the energy removed by the friction
  527. X *  force is greater than ke, then the craft will stop sometime during this
  528. X *  period -- we won't bother to calculate exactly where we stop; just zero out
  529. X *  the x and y force and velocity components.
  530. X */
  531. X
  532. X        ke = 0.5 * FWeight / a * sqrt (c->Cg.x * c->Cg.x +
  533. X            c->Cg.y * c->Cg.y);
  534. X        ke += pow(sqrt(Fg.x * Fg.x + Fg.y * Fg.y), 2.0) *
  535. X            halfDeltaTSquared * a / FWeight;
  536. X        be = pow(Fg.z * muKinetic, 2.0) * halfDeltaTSquared * a / FWeight;
  537. X        if (be >= ke) {
  538. X            Fg.x = 0.0;
  539. X            Fg.y = 0.0;
  540. X            c->Cg.x = 0.0;
  541. X            c->Cg.y = 0.0;
  542. X        }
  543. X        else {
  544. X
  545. X/*
  546. X *  Getting to this point means that we're rolling along the ground (and not stopping)
  547. X *  -- make sure our roll is zeroed, then cancel the local Y-component of our
  548. X *  velocity vector (tires don't roll sideways) and then calculate the drag
  549. X *  contributed by the rolling wheels.
  550. X */
  551. X
  552. X            c->curRoll = 0.0;
  553. X            VTransform (&(c->Cg), &(c->Itrihedral), &V);
  554. X            V.y = 0.0;
  555. X            VTransform (&V, &(c->trihedral), &(c->Cg));
  556. X            D = Fg.z * muKinetic;
  557. X            Vmag = mag (c->Cg);
  558. X            if (Vmag > 0.0) {
  559. X                Fg.x -= D * c->Cg.x / Vmag;
  560. X                Fg.y -= D * c->Cg.y / Vmag;
  561. X                Fg.z -= D * c->Cg.z / Vmag;
  562. X            }
  563. X        }
  564. X        }
  565. X
  566. X
  567. X/* Nose wheel steering is only active when we cannot lift off -- cancel z */
  568. X
  569. X        Fg.z = 0.0;
  570. X        calcGForces (c, &Fg, FWeight);
  571. X
  572. X    }
  573. X    else {
  574. X
  575. X/*
  576. X *  Resolve moments
  577. X */
  578. X
  579. X        ap = fsign (c->p);
  580. X        aq = fsign (c->q);
  581. X        ar = fsign (c->r);
  582. X        if (c->groundContact == 0) {
  583. X        ap = (c->Sa * c->cinfo->effAileron * q - c->cinfo->LDamp *
  584. X            ap * c->p * c->p * 0.5 );
  585. X            ap += (c->beta - c->Sr * c->cinfo->effRudder) * c->cinfo->CLbeta * q;
  586. X        ap += c->damageCL * q;
  587. X        ap /= c->cinfo->I.m[0][0];
  588. X        }
  589. X        else
  590. X        ap = 0.0;
  591. X#ifdef notdef
  592. X        aq = (CM * q - c->cinfo->MDamp * aq * c->q * c->q * 0.5) /
  593. X        c->cinfo->I.m[1][1];
  594. X        ar = (CN * q - c->cinfo->NDamp * ar * c->r * c->r * 0.5) /
  595. X        c->cinfo->I.m[2][2];
  596. X
  597. X        deltaRoll  = c->p * deltaT + ap * halfDeltaTSquared;
  598. X        deltaPitch = c->q * deltaT + aq * halfDeltaTSquared;
  599. X        deltaYaw   = c->r * deltaT + ar * halfDeltaTSquared;
  600. X        c->p = c->p + ap * deltaT;
  601. X        c->q = c->q + aq * deltaT;
  602. X        c->r = c->r + ar * deltaT;
  603. X#endif
  604. X
  605. X        deltaRoll  = c->p * deltaT + ap * halfDeltaTSquared;
  606. X        c->p = c->p + ap * deltaT;
  607. X
  608. X        y = c->alpha - c->Se * c->cinfo->effElevator;
  609. X        twoOrder (CM * q / c->cinfo->I.m[1][1],
  610. X        c->cinfo->MDamp, y, c->q, &newy, &(c->q));
  611. X        deltaPitch = newy - y;
  612. X
  613. X        y = c->beta - c->Sr * c->cinfo->effRudder;
  614. X        twoOrder (CN * q / c->cinfo->I.m[2][2],
  615. X        c->cinfo->NDamp, y, c->r, &newy, &(c->r));
  616. X        deltaYaw = y - newy;
  617. X
  618. X        if (debug) {
  619. X        printf ("p = %g, q = %g, r = %g\n", c->p, c->q, c->r);
  620. X        }
  621. X
  622. X/*
  623. X *  Compute new transformation matrices
  624. X */
  625. X
  626. X        buildEulerMatrix (deltaRoll, deltaPitch, deltaYaw, &mtx);
  627. X        VMatrixMult (&mtx, &c->trihedral, &mtx1);
  628. X        c->trihedral = mtx1;
  629. X        
  630. X        transpose (&c->trihedral, &c->Itrihedral);
  631. X        euler (c);
  632. X
  633. X        craftToGround (c, &F, &Fg);
  634. X        FWeight = c->cinfo->emptyWeight + c->fuel;
  635. X
  636. X        if ((c->fuel -= fuelUsed(c) + c->leakRate * deltaT) <= 0.0) {
  637. X        c->fuel = 0.0;
  638. X        c->curThrust = 0.0;
  639. X        }
  640. X
  641. X        Fg.z += FWeight;
  642. X
  643. X/*
  644. X *  If we are on the ground, level the wings and compute wheel drag forces.  Wheel
  645. X *  drag always acts in the opposite direction of the velocity vector.
  646. X */
  647. X
  648. X        if (c->groundContact) {
  649. X        c->curRoll = 0.0;
  650. X            buildEulerMatrix (c->curRoll, c->curPitch,
  651. X            c->curHeading, &(c->trihedral));
  652. X            transpose (&c->trihedral, &c->Itrihedral);
  653. X
  654. X        VTransform (&(c->Cg), &(c->Itrihedral), &V);
  655. X        V.y = 0.0;
  656. X        VTransform (&V, &(c->trihedral), &(c->Cg));
  657. X        D = Fg.z * muKinetic;
  658. X        Vmag = mag (c->Cg);
  659. X        Fg.x -= D * c->Cg.x / Vmag;
  660. X        Fg.y -= D * c->Cg.y / Vmag;
  661. X        Fg.z -= D * c->Cg.z / Vmag;
  662. X        }
  663. X
  664. X        if (debug) {
  665. X            printf ("v = %g, Fg = { %g, %g, %g }\n", FPStoKTS(Vmag),
  666. X            Fg.x, Fg.y, Fg.z);
  667. X            printf ("F = { %g, %g, %g }\n",
  668. X            F.x, F.y, F.z);
  669. X        }
  670. X
  671. X
  672. X/*
  673. X *  Are we on the ground without the prospect of gaining altitude?
  674. X *  If so, cancel the vertical force component.
  675. X */
  676. X
  677. X        if (c->groundContact && Fg.z > 0.0)
  678. X        Fg.z = 0.0;
  679. X
  680. X        calcGForces (c, &Fg, FWeight);
  681. X
  682. X
  683. X    }
  684. X
  685. X/*
  686. X *  Update our position (in flight mode).
  687. X */
  688. X
  689. X    if (positionUpdated == 0) {
  690. X
  691. X        c->Sg.x += c->Cg.x * deltaT + Fg.x / FWeight
  692. X            * a * halfDeltaTSquared;
  693. X        c->Sg.y += c->Cg.y * deltaT + Fg.y / FWeight
  694. X            * a * halfDeltaTSquared;
  695. X        c->Sg.z += c->Cg.z * deltaT + Fg.z / FWeight
  696. X            * a * halfDeltaTSquared;
  697. X
  698. X    }
  699. X
  700. X    c->Cg.x += Fg.x / FWeight * a * deltaT;
  701. X    c->Cg.y += Fg.y / FWeight * a * deltaT;
  702. X    c->Cg.z += Fg.z / FWeight * a * deltaT;
  703. X
  704. X    if (debug) {
  705. X        printf ("Altitude = %g\n", -c->Sg.z);
  706. X        printf ("Euler angles { %g, %g, %g }\n", RADtoDEG(c->curRoll),
  707. X            RADtoDEG(c->curPitch), RADtoDEG(c->curHeading));
  708. X        printf ("Cg = { %g, %g, %g }\n", c->Cg.x, c->Cg.y, c->Cg.z);
  709. X        printf ("Sg = { %g, %g, %g }\n", c->Sg.x, c->Sg.y, c->Sg.z);
  710. X
  711. X        printf ("X = { %g, %g, %g }\n", c->trihedral.m[0][0],
  712. X            c->trihedral.m[1][0], c->trihedral.m[2][0]);
  713. X        printf ("Z = { %g, %g, %g }\n\n", c->trihedral.m[0][2],
  714. X            c->trihedral.m[1][2], c->trihedral.m[2][2]);
  715. X    }
  716. X
  717. X
  718. X/*
  719. X *  Normalize the vertical position.  If our altitude is now below our
  720. X *  contact threshold, mark us as having "groundContact" and adjust the
  721. X *  altitude.
  722. X */
  723. X
  724. X    if (c->Sg.z >= - c->cinfo->groundingPoint.z) {
  725. X        c->groundContact = 1;
  726. X        c->Sg.z = - c->cinfo->groundingPoint.z;
  727. X
  728. X/*
  729. X *  If the vertical velocity component is too great, the plane has crashed ...
  730. X */
  731. X
  732. X        if (c->Cg.z > c->cinfo->crashC)
  733. X            return 1;
  734. X        else
  735. X            c->Cg.z = 0.0;
  736. X
  737. X    }
  738. X    else {
  739. X        c->groundContact = 0;
  740. X        c->flags &= ~FL_NWS;
  741. X    }
  742. X
  743. X
  744. X    return 0;
  745. X}
  746. END_OF_FILE
  747. if test 16393 -ne `wc -c <'acm/fsim/pm.c'`; then
  748.     echo shar: \"'acm/fsim/pm.c'\" unpacked with wrong size!
  749. fi
  750. # end of 'acm/fsim/pm.c'
  751. fi
  752. echo shar: End of archive 8 \(of 9\).
  753. cp /dev/null ark8isdone
  754. MISSING=""
  755. for I in 1 2 3 4 5 6 7 8 9 ; do
  756.     if test ! -f ark${I}isdone ; then
  757.     MISSING="${MISSING} ${I}"
  758.     fi
  759. done
  760. if test "${MISSING}" = "" ; then
  761.     echo You have unpacked all 9 archives.
  762.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  763. else
  764.     echo You still need to unpack the following archives:
  765.     echo "        " ${MISSING}
  766. fi
  767. ##  End of shell archive.
  768. exit 0
  769. -- 
  770. Riley Rainey            Internet: riley@mips.com
  771. MIPS Computer Systems        Phone:    +1 214 770-7979
  772. Dallas, Texas
  773.